use std::path::Path;

use clap::{Arg, ArgAction, ArgMatches, Command};

use crate::environment::environment;
use crate::index::index;
use crate::runtime::runtime::path;
use crate::util::util::installer::installer;
use crate::util::util::system;

pub const NAME: &'static str = "ins";

pub fn new() -> Command {
    let mut command = Command::new(NAME).about("工具包安装器，用于处理工具的安装操作");

    command = command.arg(Arg::new("overwrite").action(ArgAction::SetTrue).long("overwrite").help("覆盖安装，设置该参数时将完全移除已安装的内容并重新安装，请谨慎使用"));
    command = command.arg(Arg::new("source-only").action(ArgAction::SetTrue).long("source-only").help("仅从源码安装，这将跳过预构建的安装包，这仅对一些允许从源码编译的工具有效"));
    command = command.arg(Arg::new("switch-to").action(ArgAction::SetTrue).long("switch-to").help("安装完成后设置到全局运行时环境"));
    command = command.arg(Arg::new("switch-to-project").action(ArgAction::SetTrue).long("switch-to-project").help("安装完成后设置到项目运行时环境"));
    command = command.arg(Arg::new("name").required(true).help("工具名称"));
    command = command.arg(Arg::new("version").help("工具版本，此参数是可选地，未传入时取最新版本"));

    command
}

pub fn action(args: &ArgMatches) {
    let name = args.get_one::<String>("name").unwrap();
    let software = index::index().get(name.as_str());
    if software.is_none() {
        println!("未知的工具名称: {}", name);

        return;
    }

    let software = software.unwrap();
    let last = software.get_versions()[0].to_string();

    let mut version = args.get_one::<String>("version");
    if version.is_none() {
        version = Some(&last);
    }

    let version_name = version.unwrap();
    if environment::is_installed(name, version_name) && args.get_flag("overwrite") {
        println!("工具[{}]的[{}]版本已安装，若要覆盖安装请指定--overwrite选项", name, version_name);

        return;
    }

    let version = software.get_version(version_name);
    if version.is_none() {
        println!("工具[{}]未找到版本[{}]配置，请更新本地索引或反馈此问题", name, version_name);

        return;
    }

    let version = version.unwrap();

    if Path::new(path::DEM_SOFTWARE_PATH).join(name).join(version.version.as_str()).join(".installing").exists() {
        println!("工具[{}]的版本[{}]正在安装中，请等待安装完成", name, version_name);

        return;
    }

    let result = installer::Installer::install(name, version, args.get_flag("source-only"));
    if result.is_err() {
        let path = Path::new(path::DEM_SOFTWARE_PATH).join(name).join(version_name);
        let _ = system::fs::remove_dir_all(path.to_str().unwrap());
        println!("安装工具[{}]的版本[{}]失败，失败原因: {}", name, version_name, result.unwrap_err());

        return;
    }

    println!("安装完成");

    let global = environment::global_mut();
    if args.get_flag("switch-to") {
        let result = global.switch_to(name.to_string(), version_name.to_string());
        if result.is_err() {
            println!("设置工具[{}]的[{}]版本到全局环境时失败: {}", name, version_name, result.unwrap_err());

            return;
        }

        println!("工具[{}]的[{}]版本已设置到全局环境", name, version_name);
    } else {
        if !global.is_set(name) {
            println!("检测到该工具未配置到全局环境，将自动设置当前版本为运行时环境");

            let result = global.switch_to(name.to_string(), version_name.to_string());
            if result.is_err() {
                println!("设置工具[{}]的[{}]版本到全局环境时失败: {}", name, version_name, result.unwrap_err());

                return;
            }
        }
    }

    if args.get_flag("switch-to-project") {
        let project = environment::project_mut();
        let result = project.switch_to(name.to_string(), version_name.to_string());
        if result.is_err() {
            println!("设置工具[{}]的[{}]版本到项目环境时失败: {}", name, version_name, result.unwrap_err());

            return;
        }

        println!("工具[{}]的[{}]版本已设置到项目环境", name, version_name);
    }
}